package com.yc.d0415;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class 线程池 {

    public static void main(String[] args) throws InterruptedException {
        // 数量不限的线程池
        final ExecutorService es1 = Executors.newCachedThreadPool();
        // 指定数量的线程池
        final ExecutorService es2 = Executors.newFixedThreadPool(10);
        // 延时或定时执行任务的线程池
        Executors.newScheduledThreadPool(10);

        ThreadPool threadPool = new ThreadPool(3);

        for (int i = 0; i <20; i++) {
            final int ii = i;
            threadPool.execute(()->{
                System.out.println("工作: " + ii + " 开始!");
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("工作: " + ii + " 结束!");
            });

//            es2.execute(()->{
//                System.out.println("工作: " + ii + " 开始!");
//                try {
//                    Thread.sleep(200);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                System.out.println("工作: " + ii + " 结束!");
//            });
        }
    }
}

class ThreadPool{
    Map map = new Hashtable<>();
    List list = new Vector<>();

    // 将非同步集合 转成 同步集合
    // 线程池
    Set<InnerThread> pool = Collections.synchronizedSet(new HashSet<>());
    // 运行的线程池
    Set<InnerThread> runs = Collections.synchronizedSet(new HashSet<>());

    ThreadPool( int size){
        for (int i = 0; i < size; i++) {
            InnerThread t = new InnerThread();
            t.start();
            pool.add(t);
        }
    }

    synchronized void execute(Runnable command) throws InterruptedException {
        while (true){
            try {
                //  提取 pool 中的 线程  => 通知线程
                // 随机获取一个set中的元素
                final InnerThread thread = pool.stream().findFirst().get();
                pool.remove(thread);
                runs.add(thread);
                thread.execute(command);
                return;
            }catch (NoSuchElementException e){
                // 线程池中没有线程了
                System.out.println("线程耗尽, 进入等待状态!!");
                this.wait();
            }
        }
    }

    class InnerThread extends Thread {
        // 线程要执行的代码
        Runnable runnable;

        // 执行代码
        public synchronized void execute(Runnable runnable){
            this.runnable = runnable;
            this.notifyAll();
        }

        @Override
        public void run() {
            while(true){
                try {
                    synchronized (this){
                        this.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 同步 + 等待
                runnable.run();
                synchronized (ThreadPool.this){
                    // 执行结束, 将线程归还给线程池
                    runs.remove(this);
                    pool.add(this);
                    ThreadPool.this.notifyAll();
                }
            }
        }
    }

}

